package araxy.blog;

import araxy.blog.entity.QuartzBean;
import araxy.blog.service.UserService;
import araxy.blog.task.GitSyncJob;
import araxy.blog.utils.GitUtil;
import araxy.blog.utils.QuartzUtil;
import araxy.blog.utils.RedisUtil;
import araxy.blog.utils.SpringContextsUtil;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.SQLException;
import java.util.Objects;

public class EnvironmentCheck {
    public static ApplicationContext ac = SpringContextsUtil.getApplicationContext();
    public static Environment env = ac.getEnvironment();

    public static void check() {
        databaseCheck();
        adminCheck();
        storageCheck();
        redisCheck();
        gitCheck();
        tasksSetup();
    }

    private static void tasksSetup() {

        if ("true".equals(env.getProperty("storage.git.autosync"))) {
            try {
                QuartzBean gitSync = (QuartzBean) ac.getBean("gitSyncTask");
                QuartzUtil.createScheduleJob(gitSync);
                QuartzUtil.getScheduler().start();
            } catch (SchedulerException ignored) {

            }
        }

    }

    private static void databaseCheck() {
        DataSource dataSource = ac.getBean(DataSource.class);
        try {
            dataSource.getConnection();
        } catch (SQLException throwables) {
            System.out.println("======================================");
            System.out.println("数据库连接失败，程序自动退出");
            System.out.println("======================================");
            System.exit(-2);
        }
    }

    private static void storageCheck() {
        String localStorage = env.getProperty("storage.local");
        if ("".equals(localStorage) || localStorage == null ) {
            System.out.println("未设置本地存储路径,存储路径默认为同目录的storage目录");
            localStorage = System.getProperty("user.dir") + "/storage";
        }
        Path storage = Paths.get(localStorage);
        TotalStatus.setStorage(storage);
        System.out.println("当前存储路径为：\n"+ storage.toString());
        Path articlesPath = Paths.get(storage.toString(),"articles");
        Path tempPath = Paths.get(storage.toString(),"temp");
        if (    !Files.exists(articlesPath) ||
                !Files.exists(tempPath)     ) {
            try {
                Files.createDirectories(articlesPath);
                Files.createDirectories(tempPath);
            } catch (IOException exception) {
                exception.printStackTrace();
            }
        }
    }

    private static void gitCheck() {
        String repoUrl = env.getProperty("storage.git.repo.url");
        if ("".equals(repoUrl)) {
            repoUrl = null;
        }
        String account = env.getProperty("storage.git.cert.account");
        if ("".equals(account)) {
            account = null;
        }
        String password = env.getProperty("storage.git.cert.password");
        if ("".equals(password)) {
            password = null;
        }
        String token = env.getProperty("storage.git.cert.token");
        if ("".equals(token)) {
            token = null;
        }

        if ( repoUrl == null ||  !((account != null && password != null) || (token != null)) ) {
            return;
        }
        Path path = Paths.get(TotalStatus.getStorage().toString(),"articles");
        try {
            GitUtil.init(path.toString(),repoUrl);
            TotalStatus.setGit(true);
        } catch (GitAPIException | IOException | URISyntaxException ignored) {

        }

    }

    private static void redisCheck() {
        String host = env.getProperty("spring.redis.host");
        if ("".equals(host)) {
            host = null;
        }
        String port = env.getProperty("spring.redis.port");
        if ("".equals(port)) {
            port = null;
        }
        if (host == null || port == null) {
            return;
        }
        String pong = null;
        try {
            pong = Objects.requireNonNull(RedisUtil.getRedisTemplate().getConnectionFactory()).getConnection().ping();
        } catch (Exception ignored) {

        }
        if (!"PONG".equals(pong)) {
            return;
        }
        TotalStatus.setRedis(true);
    }

    private static void adminCheck() {
        UserService userService = (UserService) ac.getBean("userServiceImpl");
        Integer cnt = userService.countAllAdmin();
        if (cnt > 0) {
            return;
        }
        String adminUsername = env.getProperty("admin.username");
        if ("".equals(adminUsername) || adminUsername == null) {
            adminUsername = env.getProperty("admin.defaultUsername");
        }
        String adminPassword = env.getProperty("admin.password");
        if ("".equals(adminPassword) || adminPassword == null) {
            adminPassword = env.getProperty("admin.defaultPassword");
        }
        userService.addUser(adminUsername,adminPassword,adminUsername,true);
    }

}
